package fr.utbm.tx52;

import java.net.*;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;


/**
 * La classe principale du serveur, elle va attendre les connexion entrantes.
 */
public class Server {

	/**
	 * Port utilisé sur le serveur
	 */
	private static final int port = 8080;
	
	
	/**
	 * Liste des clients connectés <Téléphone, Socket>
	 */
	private Map<String, ClientThread> m_clients = new HashMap<String, ClientThread>();


	public Server()
	{
		try
		{
			ServerSocket s = new ServerSocket(port);

			System.out.println("- Serveur launched -");

			new Commande(this); // lance le thread de gestion des commandes

			while (true) // attente en boucle de connexion (bloquant sur ss.accept)
			{
				new ClientThread(s.accept(), this); // un client se connecte, un nouveau thread client est lancé
				System.out.println("- Client connected -");
			}
		}
		catch (Exception e) { 
			System.out.println("- Erreur lors du lancement du serveur -");
			System.out.println(e.getMessage());
		}
	}


	/** 
	 * Supprime un client de la liste
	 * 
	 * @param id
	 * 			L'identifiant (numéro de téléphone) du client
	 */
	synchronized public void delClient(String id)
	{
		System.out.println("Deconnexion du client " + id);
		m_clients.remove(id);
	}

	
	/** 
	 * Ajout d'un client dans la liste
	 * 
	 * @param id
	 * 			L'identifiant (numéro de téléphone) du client
	 * @param ct
	 * 			Le thread du client pour l'identifier facilement
	 */
	synchronized public void addClient(String id, ClientThread ct)
	{
		if ( id.equals("") ) {
			return;
		}
		
		System.out.println("Connexion du client " + id);
		m_clients.put(id, ct);
		
		////////////////////// il faudra ajouter l'envoi des messages en attente au client concerné à sa connexion
	}


	/**
	 * Affiche la liste des clients connectés
	 */
	synchronized public void printClientList()
	{
		System.out.println("Liste des clients connectés\n---------------------------");
		for (Iterator<Entry<String, ClientThread>> it = m_clients.entrySet().iterator(); it.hasNext(); ) {
			System.out.println(it.next());
		}
		System.out.println("---------------------------");
	}
	
	
	/**
	 * Envoi le message au donné au client donné par son ID
	 * 
	 * @param ID
	 * 			L'identifiant du client, son numéro de téléphone
	 * @param type
	 * 			Le type du message
	 * @param content
	 * 			Le contenu du message
	 */
	public void sendMessageToClient(String id, String type, String content)
	{
		if ( ! m_clients.containsKey(id) ) {
			return;
		}
		
		ClientThread ct = m_clients.get(id);
		ct.sendMessage(type, content);
	}
	
	/**
	 * Envoi d'un message de type nouveau media disponible au client donné
	 *
	 * @param id
	 * 			Identifiant du client, son numéro de téléphone
	 * @param from
	 * 			L'identifiant du client qui envoi la photo (son numéro de téléphone)
	 * @param photo
	 * 			Le chemin vers la photo à partager
	 * @param sound
	 * 			Le chemin vers le fichier son, peut être null
	 * @param comment
	 * 			Le commentaire associé à la photo
	 */
	public void sendMedia(String id, String from, String photo, String sound, String comment)
	{
		if ( ! m_clients.containsKey(id) ) {
			return;
		}
		
		ClientThread ct = m_clients.get(id);

		// envoi du message selon le pattern décidé
		String message = from + " " + photo + " " + (sound != null ? sound : "null") + " " + comment;
		ct.sendMessage("@", message);
		
		// envoi de l'image
		ct.sendFile(photo);
		
		// envoi du son s'il existe
		if (sound != null) {
			ct.sendFile(sound);
		}

	}
}
